package com.escom.service;

import android.content.Context;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;

import com.escom.dao.ArritmiaDAO;
import com.escom.dao.ConsultaDAO;
import com.escom.dao.HistoriaFamiliarDAO;
import com.escom.dao.HospitalDAO;
import com.escom.dao.MedicoDAO;
import com.escom.dao.PacienteDAO;
import com.escom.entidad.ArritmiaVO;
import com.escom.entidad.ConsultaVO;
import com.escom.entidad.EnfermedadVO;
import com.escom.entidad.HistoriaFamiliarVO;
import com.escom.entidad.HospitalVO;
import com.escom.entidad.MngSyncVO;
import com.escom.entidad.PacienteVO;
import com.escom.entidad.ParentescoVO;
import com.escom.healthlc.entidad.EstudioORM;
import com.escom.utils.Constantes;

import org.springframework.http.client.ClientHttpRequestFactory;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.http.client.SimpleClientHttpRequestFactory;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.web.client.ResourceAccessException;
import org.springframework.web.client.RestTemplate;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OptionalDataException;
import java.io.OutputStream;
import java.io.StreamCorruptedException;
import java.net.Socket;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.StringTokenizer;

/**
 * Created by Carlos on 15/04/2014.
 */
public class SincronizarWebService implements Runnable {

    private Handler handler;
    private Context context;
    private String idMedico;


    @Override
    public void run() {
        syncMngPacientes();
        syncEstudioORM();
    }

    private void syncMngPacientes() {
        Message msgObj = handler.obtainMessage();
        Bundle bundleMessage = new Bundle();
        int messageResponse = -1;
        String url = "http://" + Constantes.IP_PC + ":8080/TrabajoTerminal-web/rest/mngPacienteWebService?" +
                "idMedico={query}";
        RestTemplate restTemplate = new RestTemplate();
        restTemplate.getMessageConverters().add(new MappingJackson2HttpMessageConverter());
        restTemplate.getMessageConverters().add(new StringHttpMessageConverter());

        ClientHttpRequestFactory clientHttpRequestFactory = restTemplate.getRequestFactory();
        int timeout = 10000;
        if (clientHttpRequestFactory instanceof SimpleClientHttpRequestFactory) {
            ((SimpleClientHttpRequestFactory) clientHttpRequestFactory).setConnectTimeout(timeout);
            ((SimpleClientHttpRequestFactory) clientHttpRequestFactory).setReadTimeout(timeout);
        } else if (clientHttpRequestFactory instanceof HttpComponentsClientHttpRequestFactory) {
            ((HttpComponentsClientHttpRequestFactory) clientHttpRequestFactory).setReadTimeout(timeout);
            ((HttpComponentsClientHttpRequestFactory) clientHttpRequestFactory).setConnectTimeout(timeout);
        }

        MngSyncVO managmentPaciente = null;
        try {
            managmentPaciente = restTemplate.getForObject(url, MngSyncVO.class, idMedico);
        } catch (ResourceAccessException exResource) {
            Log.e(Constantes.LOG_ID, exResource.fillInStackTrace().toString());
            messageResponse = Constantes.ERROR_COMUNICACION;
        }
        if (managmentPaciente != null) {
            Log.d(Constantes.LOG_ID, "ManagmentPaciente Diferente de nulo");
            EnfermedadVO[] enfermeda = managmentPaciente.getEnfermedad();
            ParentescoVO[] parentesco = managmentPaciente.getParentesco();
            HistoriaFamiliarVO[] historiaFamiliar = managmentPaciente.getHistoriaFamiliar();
            ConsultaVO[] consultas = managmentPaciente.getConsultas();
            ArritmiaVO[] arritmias = managmentPaciente.getArritmia();
            PacienteVO[] pacientes = managmentPaciente.getPacientes();
            HospitalVO[] hosptales = managmentPaciente.getHospital();

            PacienteDAO pacienteDAO = new PacienteDAO(context);
            pacienteDAO.setIdMedico(idMedico);
            pacienteDAO.createPacientes(pacientes);

            HistoriaFamiliarDAO historiaFamiliarDAO = new HistoriaFamiliarDAO(context);
            historiaFamiliarDAO.createEnfermedad(enfermeda);
            historiaFamiliarDAO.createParentesco(parentesco);
            historiaFamiliarDAO.createHistoriaFamiliar(historiaFamiliar);

            ArritmiaDAO arritmiaDAO = new ArritmiaDAO(context);
            arritmiaDAO.createMultipleArrimita(arritmias);

            HospitalDAO hospitalDAO = new HospitalDAO(context);
            hospitalDAO.createMultipleHospital(hosptales);

            ConsultaDAO consultaDAO = new ConsultaDAO(context);
            consultaDAO.createMultipleConsulta(consultas);

        }

        if (messageResponse == -1) {
            messageResponse = Constantes.EXITO;
        }
        /*bundleMessage.putInt("message", messageResponse);
        msgObj.setData(bundleMessage);
        handler.sendMessage(msgObj);*/
    }

    private void syncEstudioORM() {
        Message msgObj = handler.obtainMessage();
        Bundle bundleMessage = new Bundle();
        int messageResponse = -1;

        try {
            File directorio = new File("/storage/sdcard0/HealthLC/");
            File[] fileInto = directorio.listFiles();
            Log.d(Constantes.LOG_ID, this.getClass().getName() + " Archivos dentro directorio " + fileInto.length);
            MedicoDAO medicoDAO = new MedicoDAO(context);
            for (int i = 0; i < fileInto.length; i++) {
                File fileObject = fileInto[i];
                String fileName = fileObject.getName();
                StringTokenizer sT = new StringTokenizer(fileName, "-");
                String dateFileString = sT.nextToken();
                String idMedicoFile = sT.nextToken();
                idMedicoFile = idMedicoFile.replace(".txt", "");
                Log.d(Constantes.LOG_ID, this.getClass().getName() + " dateFileString " + dateFileString);
                Log.d(Constantes.LOG_ID, this.getClass().getName() + " idMedicoFile " + idMedicoFile);
                String json = "";
                Socket socket = null;
                if(idMedicoFile.equals(idMedico)){
                    String ultimaActualizacion = medicoDAO.obetnerFechaUltimoUpdate(idMedico);
                    Log.d(Constantes.LOG_ID, this.getClass().getName() + " Ultima actualización " + ultimaActualizacion);

                    if (ultimaActualizacion != null && !ultimaActualizacion.equals("null") && !ultimaActualizacion.equals("")) {
                        Date dateLastUpdate = new SimpleDateFormat(Constantes.FORMAT_DATE).parse(ultimaActualizacion);
                        Date dateFile = new SimpleDateFormat("yyy_MM_dd_HH_mm_ss").parse(dateFileString);
                        if(dateFile.after(dateLastUpdate)){
                            ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream(fileObject));
                            EstudioORM estudioORM = (EstudioORM) objectInputStream.readObject();
                            socket = new Socket(Constantes.IP_PC, Constantes.PORT_FILE);
                            OutputStream outputStream = socket.getOutputStream();
                            /*PrintWriter printWriter = new PrintWriter(outputStream, true);
                            printWriter.println("START-FILE");*/
                            ObjectOutputStream objectOutputStream = new ObjectOutputStream(outputStream);
                            objectOutputStream.writeObject(estudioORM);

                        }
                    }else{
                        ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream(fileObject));
                        EstudioORM estudioORM = (EstudioORM) objectInputStream.readObject();
                        socket = new Socket(Constantes.IP_PC, Constantes.PORT_FILE);
                        OutputStream outputStream = socket.getOutputStream();
                            /*PrintWriter printWriter = new PrintWriter(outputStream, true);
                            printWriter.println("START-FILE");*/
                        ObjectOutputStream objectOutputStream = new ObjectOutputStream(outputStream);
                        objectOutputStream.writeObject(estudioORM);
                    }
                }
                if(socket != null){
                    socket.close();
                }
            }
            medicoDAO.insertarFechaUltimoUpdate(idMedico);
        } catch (ResourceAccessException e) {
            e.printStackTrace();
            Log.e(Constantes.LOG_ID, e.fillInStackTrace().toString());
            messageResponse = Constantes.ERROR_COMUNICACION;
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
            Log.e(Constantes.LOG_ID, e.fillInStackTrace().toString());
            messageResponse = Constantes.ERROR_COMUNICACION;
        } catch (OptionalDataException e) {
            e.printStackTrace();
            Log.e(Constantes.LOG_ID, e.fillInStackTrace().toString());
            messageResponse = Constantes.ERROR_COMUNICACION;
        } catch (FileNotFoundException e) {
            e.printStackTrace();
            Log.e(Constantes.LOG_ID, e.fillInStackTrace().toString());
            messageResponse = Constantes.ERROR_COMUNICACION;
        } catch (StreamCorruptedException e) {
            e.printStackTrace();
            Log.e(Constantes.LOG_ID, e.fillInStackTrace().toString());
            messageResponse = Constantes.ERROR_COMUNICACION;
        } catch (IOException e) {
            e.printStackTrace();
            Log.e(Constantes.LOG_ID, e.fillInStackTrace().toString());
            messageResponse = Constantes.ERROR_COMUNICACION;
        } catch (ParseException e) {
            e.printStackTrace();
            Log.e(Constantes.LOG_ID, e.fillInStackTrace().toString());
            messageResponse = Constantes.ERROR_COMUNICACION;
        }

        if (messageResponse == -1) {
            messageResponse = Constantes.EXITO;
        }
        bundleMessage.putInt("message", messageResponse);
        msgObj.setData(bundleMessage);
        handler.sendMessage(msgObj);
    }

    public void setHandler(Handler handler) {
        this.handler = handler;
    }

    public void setContext(Context context) {
        this.context = context;
    }

    public void setIdMedico(String idMedico) {
        this.idMedico = idMedico;
    }
}
